/*
Copyright 2018-2024 New Vector Ltd.
Copyright 2017 Vector Creations Ltd
Copyright 2015 OpenMarket Ltd

SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
 */

#import "MXKRoomMemberTableViewCell.h"

@import MatrixSDK;

#import "MXKAccount.h"
#import "MXKImageView.h"
#import "MXKPieChartView.h"
#import "MXKRoomMemberCellDataStoring.h"
#import "MXKRoomMemberListDataSource.h"
#import "MXKTools.h"

#import "NSBundle+MatrixKit.h"

#import "MXKSwiftHeader.h"

@interface MXKRoomMemberTableViewCell ()
{
    NSRange lastSeenRange;
    
    MXKPieChartView* pieChartView;
}

@end

@implementation MXKRoomMemberTableViewCell

- (void)awakeFromNib
{
    [super awakeFromNib];
    
    self.typingBadge.image = [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"icon_keyboard"];
}

- (void)customizeTableViewCellRendering
{
    [super customizeTableViewCellRendering];
    
    self.pictureView.defaultBackgroundColor = [UIColor clearColor];
}

- (UIImage*)picturePlaceholder
{
    return [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"default-profile"];
}

- (void)render:(MXKCellData *)cellData
{
    // Sanity check: accept only object of MXKRoomMemberCellData classes or sub-classes
    NSParameterAssert([cellData isKindOfClass:[MXKRoomMemberCellData class]]);
    
    MXKRoomMemberCellData *memberCellData = (MXKRoomMemberCellData*)cellData;
    if (memberCellData)
    {
        mxSession = memberCellData.mxSession;
        memberId = memberCellData.roomMember.userId;
        
        self.userLabel.text = memberCellData.memberDisplayName;
        
        // Disable by default activity update mechanism (This is required in case of a reused cell).
        shouldUpdateActivityInfo = NO;
        
        // User thumbnail
        self.pictureView.mediaFolder = kMXMediaManagerAvatarThumbnailFolder;
        self.pictureView.enableInMemoryCache = YES;
        // Consider here the member avatar is stored unencrypted on Matrix media repo
        [self.pictureView setImageURI:memberCellData.roomMember.avatarUrl
                             withType:nil
                  andImageOrientation:UIImageOrientationUp
                        toFitViewSize:self.pictureView.frame.size
                           withMethod:MXThumbnailingMethodCrop
                         previewImage:self.picturePlaceholder
                         mediaManager:mxSession.mediaManager];
        
        // Shade invited users
        if (memberCellData.roomMember.membership == MXMembershipInvite)
        {
            for (UIView *view in self.subviews)
            {
                view.alpha = 0.3;
            }
        }
        else
        {
            for (UIView *view in self.subviews)
            {
                view.alpha = 1;
            }
        }
        
        // Display the power level pie
        [self setPowerContainerValue:memberCellData.powerLevel];
        
        // Prepare presence string and thumbnail border color
        NSString* presenceText = nil;
        UIColor* thumbnailBorderColor = nil;
        
        // Customize banned and left (kicked) members
        if (memberCellData.roomMember.membership == MXMembershipLeave || memberCellData.roomMember.membership == MXMembershipBan)
        {
            self.backgroundColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.0];
            presenceText = (memberCellData.roomMember.membership == MXMembershipLeave) ? [VectorL10n membershipLeave] : [VectorL10n membershipBan];
        }
        else
        {
            self.backgroundColor = [UIColor whiteColor];
            
            // get the user presence and his thumbnail border color
            if (memberCellData.roomMember.membership == MXMembershipInvite)
            {
                thumbnailBorderColor = [UIColor lightGrayColor];
                presenceText = [VectorL10n membershipInvite];
            }
            else
            {
                // Get the user that corresponds to this member
                MXUser *user = [mxSession userWithUserId:memberId];
                // existing user ?
                if (user)
                {
                    thumbnailBorderColor = [MXKAccount presenceColor:user.presence];
                    presenceText = [self lastActiveTime];
                    // Keep last seen range to update it
                    lastSeenRange = NSMakeRange(self.userLabel.text.length + 2, presenceText.length);
                    shouldUpdateActivityInfo = (presenceText.length != 0);
                }
            }
        }
        
        // if the thumbnail is defined
        if (thumbnailBorderColor)
        {
            self.pictureView.layer.borderWidth = 2;
            self.pictureView.layer.borderColor = thumbnailBorderColor.CGColor;
        }
        else
        {
            // remove the border
            // else it draws black border
            self.pictureView.layer.borderWidth = 0;
        }
        
        // and the presence text (if any)
        if (presenceText)
        {
            NSString* extraText = [NSString stringWithFormat:@"(%@)", presenceText];
            self.userLabel.text = [NSString stringWithFormat:@"%@ %@", self.userLabel.text, extraText];
            
            NSRange range = [self.userLabel.text rangeOfString:extraText];
            UIFont* font = self.userLabel.font;
            
            // Create the attributes
            NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                   font, NSFontAttributeName,
                                   self.userLabel.textColor, NSForegroundColorAttributeName, nil];
            
            NSDictionary *subAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                      font, NSFontAttributeName,
                                      [UIColor lightGrayColor], NSForegroundColorAttributeName, nil];
            
            // Create the attributed string (text + attributes)
            NSMutableAttributedString *attributedText =[[NSMutableAttributedString alloc] initWithString:self.userLabel.text attributes:attrs];
            [attributedText setAttributes:subAttrs range:range];
            
            // Set it in our UILabel and we are done!
            [self.userLabel setAttributedText:attributedText];
        }
        
        // Set typing badge visibility
        if (memberCellData.isTyping)
        {
            self.typingBadge.hidden = NO;
            [self.typingBadge.superview bringSubviewToFront:self.typingBadge];
        }
        else
        {
            self.typingBadge.hidden = YES;
        }
    }
}

+ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth
{
    // The height is fixed
    return 50;
}

- (NSString*)lastActiveTime
{
    NSString* lastActiveTime = nil;
    
    // Get the user that corresponds to this member
    MXUser *user = [mxSession userWithUserId:memberId];
    if (user)
    {
        // Prepare last active ago string
        lastActiveTime = [MXKTools formatSecondsIntervalFloored:(user.lastActiveAgo / 1000)];
        
        // Check presence
        switch (user.presence)
        {
            case MXPresenceOffline:
            {
                lastActiveTime = [VectorL10n offline];
                break;
            }
            case MXPresenceUnknown:
            {
                lastActiveTime = nil;
                break;
            }
            case MXPresenceOnline:
            case MXPresenceUnavailable:
            default:
                break;
        }
        
    }
    
    return lastActiveTime;
}

- (void)setPowerContainerValue:(CGFloat)progress
{
    // no power level -> hide the pie
    if (0 == progress)
    {
        self.powerContainer.hidden = YES;
        return;
    }
    
    // display it
    self.powerContainer.hidden = NO;
    self.powerContainer.backgroundColor = [UIColor clearColor];
    
    if (!pieChartView)
    {
        pieChartView = [[MXKPieChartView alloc] initWithFrame:self.powerContainer.bounds];
        [self.powerContainer addSubview:pieChartView];
    }
    
    pieChartView.progress = progress;
}

- (void)updateActivityInfo
{
    // Check whether update is required.
    if (shouldUpdateActivityInfo)
    {
        NSString *lastSeen = [self lastActiveTime];
        NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithAttributedString:self.userLabel.attributedText];
        if (lastSeen.length)
        {
            [attributedText replaceCharactersInRange:lastSeenRange withString:lastSeen];
            
            // Update last seen range
            lastSeenRange.length = lastSeen.length;
        }
        else
        {
            // remove presence info
            lastSeenRange.location -= 1;
            lastSeenRange.length += 2;
            [attributedText deleteCharactersInRange:lastSeenRange];
            
            shouldUpdateActivityInfo = NO;
        }
        
        [self.userLabel setAttributedText:attributedText];
    }
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // Round image view
    [_pictureView.layer setCornerRadius:_pictureView.frame.size.width / 2];
    _pictureView.clipsToBounds = YES;
}

@end
